package com.order.manager.Config;

import com.alibaba.fastjson2.JSONObject;
import com.order.manager.Model.other.RestBean;
import com.order.manager.filter.JwtFilter;
import com.order.manager.service.AuthUserDetailService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Resource
    AuthUserDetailService authUserDetailService;
    @Resource
    JwtFilter jwtFilter;

    /**
     * school
     * student
     * student_sender
     * shop
     *
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                /**
                 * 57个接口
                 */
                .requestMatchers("/api/auth/qrcode/**").permitAll()//验证码接口
                .requestMatchers("/img/**").permitAll()//图片资源
                .requestMatchers("/api/auth/login").permitAll()//用户登录接口
                .requestMatchers("/api/auth/student/count").permitAll()//获取所有学生用户的数量
                .requestMatchers("/api/auth/order/count").permitAll()//获取订单数量
                .requestMatchers("/api/auth/sender/count").permitAll()//获取配送员数量
                .requestMatchers("/api/auth/register").permitAll()//用户注册接口
                .requestMatchers("/api/upload/img/**").permitAll()//图片上传接口
                .requestMatchers("/api/upload/img/img-d/**").permitAll()//图片上传接口
                .requestMatchers("/api/order/apply/**").hasAnyAuthority("student","student_sender")//用户支付
                .requestMatchers("/api/order/create").hasAnyAuthority("student","student_sender")//用户创建订单
                .requestMatchers("/api/order/orderForShop/**").hasAnyAuthority("shop")//商店查询本商店的订单
                .requestMatchers("/api/order/query").hasAnyAuthority("student","student_sender")//返回自己的订单
                .requestMatchers("/api/order/refund/**").hasAnyAuthority("student","student_sender")//用户退款
                .requestMatchers("/api/order/view/**").hasAnyAuthority("student","student_sender","shop")//用户查看订单信息
                .requestMatchers("/api/shop/get/**").hasAnyAuthority("student","student_sender","shop","school")//查看某一店铺的信息
                .requestMatchers("/api/shop/info").hasAnyAuthority("shop")//查看本店铺的信息
                .requestMatchers("/api/shop/insert").permitAll()//开设店铺
                .requestMatchers("/api/shop/query/school/**").hasAnyAuthority("school")//查看了所有的商店信息
                .requestMatchers("/api/shop/select/collect/**").hasAnyAuthority("student","student_sender")//查看自己收藏的店铺
                .requestMatchers("/api/shop/select/**").hasAnyAuthority("student","student_sender")//查看了审核通过的店铺信息
                .requestMatchers("/api/shop/show").hasAnyAuthority("shop")//店铺的一些图标信息
                .requestMatchers("/api/shop/size").permitAll()//返回审核通过的店铺
                .requestMatchers("/api/shop/update").hasAnyAuthority("shop")//店铺更新自己的店铺信息
                .requestMatchers("/api/shop/update/state").hasAnyAuthority("shop","school")//店铺的审核状态
                .requestMatchers("/api/feedback/create").hasAnyAuthority("student","student_sender")//反馈信息的创建
                .requestMatchers("/api/feedback/freeback/**").hasAnyAuthority("school")//回复反馈信息
                .requestMatchers("/api/evaluate/create").hasAnyAuthority("student","student_sender")//评价信息的创建
                .requestMatchers("/api/evaluate/select/shopId/**").hasAnyAuthority("shop","student","student_sender")//查看了某个商店的评价
                .requestMatchers("/api/evaluate/select/**").hasAnyAuthority("student","student_sender","shop")//查看了某个订单的订单信息
                .requestMatchers("/api/auth/add/money").hasAnyAuthority("student","student_sender")//充值接口
                .requestMatchers("/api/menu/del/**").hasAnyAuthority("shop")//删除菜品
                .requestMatchers("/api/menu/get/**").hasAnyAuthority("student","student_sender")//获取菜品
                .requestMatchers("/api/menu/insert").hasAnyAuthority("shop")//添加菜品
                .requestMatchers("/api/menu/select/**").hasAnyAuthority("student","student_sender")//获取某一商店的菜品
                .requestMatchers("/api/menu/shopSelect/**").hasAnyAuthority("shop")//商店获取某一商店的菜品
                .requestMatchers("/api/menu/update").hasAnyAuthority("shop")//更新菜品信息
                .requestMatchers("/api/sender/apply").hasAnyAuthority("student","student_sender","school")//配送员申请
                .requestMatchers("/api/sender/audit").hasAnyAuthority("school")//配送员资格审核
                .requestMatchers("/api/sender/get/order/**").hasAnyAuthority("student_sender")//配送员接单
                .requestMatchers("/api/sender/online/count").permitAll()//在线配送员的数量
                .requestMatchers("/api/sender/order/mySelf/**").hasAnyAuthority("student_sender")//配送员查看自己接单的信息
                .requestMatchers("/api/sender/query/school/**").hasAuthority("school")//学校查看配送员信息
                .requestMatchers("/api/sender/sender/state/**").hasAnyAuthority("school","student_sender")//配送员状态
                .requestMatchers("/api/sender/senderInfo").hasAuthority("student_sender")//配送员信息
                .requestMatchers("/api/complaint/select/**").permitAll()//反馈信息
                .requestMatchers("/api/userAddress/del/**").hasAnyAuthority("student","student_sender")//删除用户地址
                .requestMatchers("/api/userAddress/insert").hasAnyAuthority("student","student_sender")//增加用户地址
                .requestMatchers("/api/userAddress/select").hasAnyAuthority("student","student_sender","shop")//查询某用户的地址
                .requestMatchers("/api/userAddress/select/option").hasAnyAuthority("student","student_sender","shop")//用户获取地址列表
                .requestMatchers("/api/examineShop/apply").hasAnyAuthority("shop")//商店审核
                .requestMatchers("/api/examineShop/get/**").hasAnyAuthority("school")//获取审核信息
                .requestMatchers("/api/examineSender/examine/**").hasAuthority("school")//获取某个配送员审核信息
                .requestMatchers("/api/orderSender/find/list/**").hasAnyAuthority("student","student_sender")//配送员可以配送的订单
                .requestMatchers("/api/collect/cancel/follow/**").hasAnyAuthority("student","student_sender")//取消收藏店铺
                .requestMatchers("/api/collect/choose/**").hasAnyAuthority("student","student_sender")//用户是否关注
                .requestMatchers("/api/collect/follow/**").hasAnyAuthority("student","student_sender")//关注店铺
                .requestMatchers("/api/online/**").permitAll()

//                .requestMatchers("/api/shop/size").permitAll()//审核通过的商家数量
//                .requestMatchers("/api/sender/online/count").permitAll()//配送员在线状况
//                .requestMatchers("/api/sender/count").permitAll()//配送员总数
//                .requestMatchers("/api/auth/school/check").hasAnyAuthority("school")//检测学校权限，并更新token
//                .requestMatchers("/api/auth/student/check").hasAnyAuthority("student")//检测学生权限
//                .requestMatchers("/api/auth/student_sender/check").hasAnyAuthority("student_sender")//检测学生兼职配送员权限
//                .requestMatchers("/api/auth/student/student_sender/check").hasAnyAuthority("student_sender","student")//检测学生兼职配送员权限，返回个人信息
//                .requestMatchers("/api/auth/shop/check").hasAnyAuthority("shop")//检测商店权限
//                .requestMatchers("/api/complaint/list/**").hasAnyAuthority("school","student","student_sender","shop")//获取所有反馈数据
//                .requestMatchers("/api/complaint/freeback/**").hasAnyAuthority("school")//获取所有反馈数据
//                .requestMatchers("/api/menu/insert/*").hasAnyAuthority("shop")//商店增添菜品
//                .requestMatchers("/api/menu/del/**").hasAnyAuthority("shop")//商店删除菜品
//                .requestMatchers("/api/menu/update").hasAnyAuthority("shop")//商店更新菜品
//                .requestMatchers("/api/menu/select/**").hasAnyAuthority("shop","student","student_sender")//商店分页查询菜品
//                .requestMatchers("/api/menu/get/**").hasAnyAuthority("student","student_sender")//用户查询所有的菜品
//                .requestMatchers("/api/shop/insert/**").hasAnyAuthority("shop")//商店在创建了用户之后进行创店初始化
//                .requestMatchers("/api/shop/update").hasAnyAuthority("shop","school")//商店的更新
//                .requestMatchers("/api/shop/select/**").hasAnyAuthority("school","student","student_sender")//商店的分页查询
//                .requestMatchers("/api/shop/select/school/**").hasAnyAuthority("school")//商店的分页查询
//                .requestMatchers("/api/shop/update/state/**").hasAnyAuthority("school","shop")//更新审核状态
//                .requestMatchers("/api/shop/info/**").hasAnyAuthority("shop")//商店信息获取
//                .requestMatchers("/api/shop/get/**").hasAnyAuthority("student","student_sender","school","shop")//商店信息获取
//                .requestMatchers("/api/order/select/shop/**").hasAnyAuthority("shop")//商店获取订单信息
//                .requestMatchers("/api/order/select/user/**").hasAnyAuthority("student","student_sender")//用户获取订单信息
//                .requestMatchers("/api/order/create").hasAnyAuthority("student","student_sender")//用户获取订单信息
//                .requestMatchers("/api/order/viewMyOrder").hasAnyAuthority("student","student_sender")//用户获取订单信息
//                .requestMatchers("/api/evaluate/create").hasAnyAuthority("student","student_sender")//评价订单
//                .requestMatchers("/api/evaluate/select/**").hasAnyAuthority("student","student_sender")//查询某一个订单的评价
//                .requestMatchers("/api/evaluate/select/shopId/**").hasAnyAuthority("student","student_sender","shop")//查询某一个订单的评价
//                .requestMatchers("/api/feedback/select").hasAnyAuthority("student","student_sender")//学生查看自己的反馈信息
//                .requestMatchers("/api/feedback/create").hasAnyAuthority("student","student_sender")//学生反馈信信息
//                .requestMatchers("/api/sender/senderInfo").hasAnyAuthority("student_sender")//配送员信息
//                .requestMatchers("/api/sender/apply").hasAnyAuthority("student")//配送员申请资格
//                .requestMatchers("/api/sender/select/**").hasAnyAuthority("school")//配送员信息分页
//                .requestMatchers("/api/sender/audit").hasAnyAuthority("school")//配送员审核
//                .requestMatchers("/api/sender/getOrder/**").hasAnyAuthority("student_sender")//配送员查看自己的所有订单
//
//                .requestMatchers("/api/order/online/**").hasAnyAuthority("student_sender")//获取所有接单
//                .requestMatchers("/api/order/sender/get/**").hasAnyAuthority("student_sender")//接单
//                .requestMatchers("/api/order/endState/**").hasAnyAuthority("student_sender")//接单
//
//                .requestMatchers("/api/collect/choose/**").hasAnyAuthority("student","student_sender")//检查当前收藏状态
//                .requestMatchers("/api/collect/follow/**").hasAnyAuthority("student","student_sender")//收藏店铺
//                .requestMatchers("/api/collect/cancel/follow/**").hasAnyAuthority("student","student_sender")//取消收藏店铺
//                .requestMatchers("/**").permitAll()
                .anyRequest().authenticated());
        http.cors(cors -> cors.disable());
        http.csrf(csrf -> csrf.disable());
//        http.formLogin(login ->login.loginProcessingUrl("/api/auth/login").permitAll());
//        自定义了登录接口，所以不需要使用原接口，原接口采用session方式，而前后端分离不需要session
        http.logout(AbstractHttpConfigurer::disable);//取消默认登出页面的使用
        http.authenticationProvider(authenticationProvider());//将自己配置的PasswordEncoder放入SecurityFilterChain中
//        http.userDetailsService(authUserDetailService);
//        因为authenticationProvider接口已经配置了该UserDetailsService和PasswordEncoder
        http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));//禁用session，因为我们已经使用了JWT
        http.httpBasic(AbstractHttpConfigurer::disable);//禁用httpBasic，因为我们传输数据用的是post，而且请求体是JSON
        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);//将用户授权时用到的JWT校验过滤器
        http.exceptionHandling(except -> except.authenticationEntryPoint(this::ex));
        // 添加进SecurityFilterChain中，并放在UsernamePasswordAuthenticationFilter的前面
        return http.build();
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder());
        provider.setUserDetailsService(authUserDetailService);
        return provider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }

    @Bean//PasswordEncoder的实现类为BCryptPasswordEncoder
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    private void failureHandler(HttpServletRequest request, HttpServletResponse response,
                                AuthenticationException e) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.getWriter().write(JSONObject.toJSONString(RestBean.failure(401, e.getMessage())));
    }

    private void ex(HttpServletRequest request, HttpServletResponse response,
                    AuthenticationException e) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.getWriter().write(JSONObject.toJSONString(RestBean.failure(403, e.getMessage())));
    }

}

